import requests
import hashlib
import json
import threading
class RequestError(Exception):
    pass
class Service:
    URL={
        "login":"login",
        "repository":"repository",
        "create_person":"repository/picture/batch_single_person",
        "delete_person":"face/delete",
        "search":"retrieval_repository",
        "face_detection":"face_detection",
        "face_verify":"face/verify",
    }
    __prefix="business/api"
    __port=11180
    __repository_id=28 #人像库id
    __repository_id2=29 #人像库id

    def __init__(self,host,username,password):
        self.__host=host
        self.__username=username
        self.__session_id=None
        self.__password=hashlib.md5(password.encode(encoding='UTF-8')).hexdigest()
        self.__is_login=False
        self.__login_lock=threading.Lock()

    def __get_url(self,url):
        url=self.URL[url]
        return "http://{}:{}/{}/{}".format(self.__host,self.__port,self.__prefix,url)

    
    def request(self,url,method="get",data=None,headers={}):
        old_headers=headers
        old_data=data
        if(self.__is_login):
            self.__login_lock.acquire()
            self.__login_lock.release()

        if(self.__session_id==None):
            self.login()
            return self.request(url,method,data,headers)
        else:
            headers.update({
                "Cookie":"session_id={};".format(self.__session_id),
                "Content-Type":"application/json",
                "Accept":"application/json"
            })
        if(method=="get"):
            res = requests.get(url=url,headers=headers)
        elif (method=="post"):
            data=json.dumps(data)
            res = requests.post(url=url,data=data,headers=headers)
        elif (method=="put"):
            res = requests.put(url=url,data=json.dumps(data),headers=headers)
        elif (method=="delete"):
            res = requests.delete(url=url,headers=headers)
        
        if(res.status_code==200):
            data=json.loads(res.text)
            res.close()
            if(data["rtn"]==-70000):
                self.login()
                return self.request(url,method,old_data,old_headers)
            else:
                return data
        else:
            res.close()
            raise Exception("status_code:{},{}".format(res.status_code,res.text))
    
    
    def login(self):
        """
            登录获取token值
        """
        self.__is_login=True
        self.__login_lock.acquire()
        self.__session_id=None
        url=self.__get_url("login")
        data={
            "name":self.__username,
            "password":self.__password
        }
        headers={
            "Content-Type":"application/json",
            "Accept":"application/json"
        }
        res = requests.post(url=url,data=json.dumps(data),headers=headers)
        if(res.status_code==200):
            data=json.loads(res.text)
            res.close()
            if(data["rtn"]==0):
                self.__session_id=data["session_id"]
                self.__is_login=False
                self.__login_lock.release()
                return data
            else:
                self.__is_login=False
                self.__login_lock.release()
                raise RequestError("rtn:{},{}".format(data["rtn"],data["message"]))
        else:
            self.__is_login=False
            self.__login_lock.release()
            res.close()
            raise Exception("status_code:{},{}".format(res.status_code,res.text))

    def get_repository(self):
        #人像库获取列表或者添加
        url=self.__get_url("repository")
        return self.request(url)

    def create_repository(self,name):
        #创建人像库
        url=self.__get_url("repository")
        data={
            "name":name,
        }
        return self.request(url,"post",data)

    def delete_repository(self,id):
        #删除人像库
        url=self.__get_url("repository")
        return self.request(url+"?id={}".format(id),"delete")
    
    def update_repository(self,id,name):
        #修改人像库
        url=self.__get_url("repository")
        data={
            "id":id,
            "name":name,
        }
        return self.request(url,"put",data)

    def delete_person(self,face_image_id):
        #删除人像
        url=self.__get_url("delete_person")
        data={
            "face_image_id":face_image_id
        }
        return self.request(url,"post",data)
    
    def create_person(self,person_list):
        #添加人像
        url=self.__get_url("create_person")
        images=[]
        for index in range(len(person_list)):
            item=person_list[index]
            images.append(
                   {
                    "repository_id":self.__repository_id2,
                    "picture_image_content_base64":item["image"],
                    "person_id":item["person_id"],
                }
            )

        data={
            "images":images,
        }
        return self.request(url,"post",data)


    def search(self,image,threshold=85.0,topk=1):
        try:
            person_search=self.__search(image,self.__repository_id,threshold=85.0,topk=1)
        except Exception as e:
            person_search["rtn"]=1
        if(person_search["rtn"]==0):
            if(len(person_search["results"])>0): #服务器搜索
                return person_search
        return self.__search(image,self.__repository_id2,threshold=85.0,topk=1)

    def __search(self,image,repository_ids,threshold=85.0,topk=1):
        #搜索
        url=self.__get_url("search")
        data={
                "start":0,
                "limit":1,
                "order":{"similarity":-1},
                "extra_fields":["person_id","similarity"],
                "retrieval":{
                    "picture_image_content_base64":image,
                    "repository_ids":[repository_ids],
                    "threshold":threshold,
                    "topk":topk,
                    
                }
            }
        return self.request(url,"post",data)

        

    def face_detection(self,image):
        #人脸检测 检测人脸位置
        url=self.__get_url("face_detection")
        data={
                "image_content_base64":image,
            }
        return self.request(url,"post",data)
    
    def face_verify(self,imageA,imageB):
        #1V1比对相似度
        url=self.__get_url("face_verify")
        data={
                "image_base64_1":imageA,
                "image_base64_2":imageB,
            }
        return self.request(url,"post",data)
